package project;

import oracle.kv.FaultException;
import oracle.kv.KVStore;
import oracle.kv.Key;
import oracle.kv.Value;
import oracle.kv.ValueVersion;
/**
 * la classe d'application qui peut equillibrer
 * 
 * */
public class Application_balance extends Thread {
	// la cle de produit qui est manipule
	private int keyProduit;
	// le temps d'attente
	private long waitTime;
	// le vector d'objet store
	private Store[] stores;

	public Application_balance(Store[] stores, int keyProduit) {
		super();
		this.keyProduit = keyProduit;
		this.stores = stores;
	}

	public int getKeyProduit() {
		return keyProduit;
	}

	public void setKeyProduit(int keyProduit) {
		this.keyProduit = keyProduit;
	}

	public long getWaitTime() {
		return waitTime;
	}

	public void setWaitTime(long waitTime) {
		this.waitTime = waitTime;
	}

	@Override
	public void run() {
		// creer un objet de transaction
		Transaction_balance transaction = new Transaction_balance(stores);
		// obtenir le temps d'attente
		this.waitTime = transaction.A(keyProduit);
		System.out.println("Wait time " + "A(k" + this.keyProduit + ")" + ": "
				+ this.waitTime + " ms");

		// creer un objet de equillibrage
		Balancing balance = new Balancing(stores);
		// obtenir l'index de store de produit
		int indexStore = getIndexStore(keyProduit);
		// statistique 
		long statistics = balance.getStatistics(indexStore, false);
		boolean isOverload = false;
		
		if (statistics > balance.thresholdValue) {
			isOverload = true;
		}
		// si trop charge, equillibrer
		if (isOverload == true) {
			// obtenir le produit qui a la version maximum
			int keyProduit = balance.getOlderVersion(indexStore);
			// obtenir l'index de store qui a le charge minimum
			int minIndexStore = balance.getOverloadMin(indexStore, statistics);
			// equillibrer et deplacer
			balance.balance(indexStore, minIndexStore, keyProduit);
		}

	}

	//
	// public void isOverload(){
	// Balancing balance = new Balancing(stores);
	// balance.isOverload(indexStore);
	// }

	public int getIndexStore(int keyProduit) {
		int initIndexStore = hachage(keyProduit);
		Key key = Key.createKey("P" + keyProduit, "quality");
		int indexStore = 0;
		try {
			ValueVersion valueVersion = stores[initIndexStore].getStore().get(
					key);
			Value value = valueVersion.getValue();
			indexStore = Integer.parseInt(new String(value.getValue()));
		} catch (FaultException fe) {
			indexStore = initIndexStore;
		}
		return indexStore;
	}

	/**
	 * Fonction de hachage. Determine Pi est stocker dans quel store.
	 * 
	 * @param i
	 *            index de produit
	 * @return index de store
	 * */
	private int hachage(int i) {
		int y = 0;
		if (i >= 0 && i <= 1000)
			y = (i - 1) / Init_balance.storeSize;
		else
			y = -1;
		return y;
	}
}
